class Complie {
	constructor(vm) {
		this.$vm = vm
		this.$el = vm.$el 
		this.complieTemplate(this.$el)
	}

	complieTemplate (parent) {
		const childs = parent.childNodes
		childs.forEach(node => {
			if (this.isTextElement(node)) {
				this.complieText(node) 
			} else if (this.isElement(node)) {
				this.complieElement(node)
			}
			if (node.childNodes && node.childNodes.length) {
				this.complieTemplate(node)
			}
		});
	}

	complieElement (node) {
		const attrs = Array.from(node.attributes)
		if (!attrs.length) return
		attrs.forEach(attr => {
			const nodeName = attr.nodeName
			if (!this.isDirect(nodeName)) return
			const type = nodeName.substring(2)
			const key = attr.nodeValue
			this[type + 'Update'] && this[type + 'Update'](node, key)
		})
	}

	textUpdate (node, key) {
		node.textContent = this.$vm[key]
		new Watcher(this.$vm, key, () => {
			node.textContent = this.$vm[key]
		})
	}

	modelUpdate (node, key) {
		node.value = this.$vm[key]
		new Watcher(this.$vm, key, () => {
			node.value = this.$vm[key]
		})
		node.addEventListener('input', () => {
			this.$vm[key] = node.value
		}, false)
	}

	complieText (node) {
		const reg = /\{\{(.+?)\}\}/g
		if (!reg.test(node.textContent)) return
		// node.textContent.text(reg)
		const key = RegExp.$1.trim()
		node.textContent = this.$vm[key]
		
		new Watcher(this.$vm, key, () => {
			node.textContent = this.$vm[key]
		})
	}

	isDirect (attrName) {
		return attrName.startsWith('v-')
	}	

	isElement (node) {
		return node.nodeType === 1
	}

	isTextElement (node) {
		return node.nodeType === 3
	}

}